import torch
import numpy as np
# 创建一个5x3的未初始化的Tensor
x = torch.empty(5, 3)
print(x)

# 创建一个5x3的随机初始化的Tensor
x = torch.rand(5, 3)
print(x)

# 创建一个5x3的long型全0的Tensor
x = torch.zeros(5, 3, dtype=torch.long)
print(x)

# 直接根据数据创建
x = torch.tensor([5.5, 3])
print(x)

# 通过现有的Tensor来创建，此方法会默认重用输入Tensor的一些属性，例如数据类型，除非自定义数据类型
x = x.new_ones(5, 3, dtype=torch.float64)  # 返回的tensor默认具有相同的torch.dtype和torch.device
print(x)

x = torch.randn_like(x, dtype=torch.float) # 指定新的数据类型
print(x)

# 对角线为1，其他为0
x = torch.eye(5, 5, dtype=torch.int64)
print(x)


# 算数操作
# 加法
y = torch.rand(5, 5)
print(x + y)
print(torch.add(x, y))
result = torch.empty(5, 5)
torch.add(x, y, out=result)
print(result)

# add x to y
y.add_(x)
print(y)

y = y.new_ones(5, 5)
print(y)

# 索引
x = y[0, :]
x += 1
print(y)

print("mask:")
mask = y.ge(2)
print(mask)
print(torch.masked_select(y, mask))

# 改变形状
y = torch.eye(3, 5)
print(y)
# view仅仅是改变了对这个张量的观察角度，内部数据并未改变, 也即数据共享(更改其中的一个，另外一个也会跟着改变。)
x = y.view(-1, 3)
print(x)

# 返回一个真正的副本
x = y.clone().view(-1, 3)
x += 1
print(x)
print(y)

print(y.t())
print(y[:, :3].inverse())


# 广播机制
x = torch.arange(1, 3).view(1, 2)
print(x)

y = torch.arange(1, 4).view(3, 1)
print(y)
print(x + y)

# Tensor转NumPy
a = torch.ones(5)
b = a.numpy()
print(a, b)

a += 1
print(a, b)
b += 1
print(a, b)


# NumPy数组转Tensor
a = np.ones(5)
b = torch.from_numpy(a)
# c是一个副本(不共享内存)
c = torch.tensor(a)
print(a, b, c)

a += 1
print(a, b, c)
b += 1
print(a, b, c)
c += 1
print(a, b, c)